package com.imgo.max.fans.service;

import com.alibaba.fastjson.JSON;
import com.imgo.max.artist.constant.FansConstant;
import com.imgo.max.artist.dto.Artist;
import com.imgo.max.artist.dto.FansInfo;
import com.imgo.max.artist.dto.RankDto;
import com.imgo.max.artist.redis.FansRedisDao;
import com.imgo.max.artist.service.FansMessageService;
import com.imgo.max.artist.service.FansService;
import com.imgo.max.cache.util.CacheCommonManager;
import com.imgo.max.common.dto.APIException;
import com.imgo.max.common.dto.QueryVO;
import com.imgo.max.common.dto.ResultDO;
import com.imgo.max.common.log.CustomLogger;
import com.imgo.max.common.log.CustomLoggerFactory;
import com.imgo.max.common.result.FansResultCodeEnum;
import com.imgo.max.common.result.ModuleResultCode;
import com.imgo.max.common.util.LoggerUtils;
import com.imgo.max.common.util.page.Pagination;
import com.imgo.max.core.tools.DateUtils;
import com.imgo.max.fans.listener.FansMsgHandler;
import com.imgo.max.ranklist.service.ArtistTotalPopularityService;
import com.imgo.max.user.dto.User;
import com.imgo.max.user.service.UserCacheService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

@Service("fansService")
public class FansServiceImpl extends FansBaseServiceImpl implements FansService {
    private static final CustomLogger logger = CustomLoggerFactory.getLogger(FansServiceImpl.class);

    @Resource
    private FansRedisDao fansRedisDao;
    @Resource
    private FansMessageService fansMessageService;
    @Resource
    private UserCacheService userCacheService;
    @Autowired
    private FansMsgHandler fansMsgHandler;
    @Autowired
    CacheCommonManager cacheCommonManager;
    @Resource
    ArtistTotalPopularityService artistTotalPopularityService;

    private final static int UID_LENGTH = 32;

    private boolean uidIsValid(String uid) {
        if (StringUtils.isBlank(uid) || uid.length() < UID_LENGTH) {
            return false;
        }
        return true;
    }

    /**
     * 提供艺人 粉丝数
     */
    @Override
    public ResultDO<Integer> getFansNum(String artistUid) {
        ResultDO<Integer> resultDO = ResultDO.buildResult();
        try {
            // 艺人id为空，和勇峰确认返回错误码
            if (!uidIsValid(artistUid)) {
                throw new APIException(FansResultCodeEnum.QUERY_PARAM_ARTIST_ID_ERROR);
            }
            Integer num = fansRedisDao.getFansNum(artistUid);
            resultDO.setModule(num);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, artistUid);
        }
        return resultDO;
    }

    /**
     * 添加关注接口：
     */
    @Override
    public ResultDO collectArtist(String uid, String artistUid) {
        ResultDO resultDO = ResultDO.buildResult();
        try {
            if (!uidIsValid(uid) || !uidIsValid(artistUid)) {
                throw new APIException(FansResultCodeEnum.PARAM_IS_EMPTY_ERROR);
            }

            // 3秒内不能重复操作
            ResultDO tmpResultDo = restrictOperateTimes(uid);
            if (tmpResultDo != null) {
                return tmpResultDo;
            }
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, artistUid);
        }

        return collectArtistHandler(uid, artistUid);
    }

    private ResultDO collectArtistHandler(String uid, String artistUid) {
        String[] uidList = artistUid.split(",");
        String artId;
        ResultDO resultDO = ResultDO.buildResult();
        try {
            Integer tempInt = 0;
            // 返回第一个艺人的粉丝数
            if (uidList.length > 0) {
                artId = uidList[0];
                if (uidIsValid(artId)) {
                    tempInt = getFansNum(artId, true);
                }
            }
            for (int i = 0; i < uidList.length; i++) {
                artId = uidList[i];
                if (uidIsValid(artId)) {
                    // 更新数据库的任务由消息队列来通知
                    fansMessageService.collectArtist(uid, artId);
                }

            }
            resultDO.setModule(tempInt);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, uid, artistUid);
        }
        return resultDO;
    }

    /**
     * 批量增加粉丝接口：
     *
     * @param uid
     * @param artistUids
     * @return
     */
    @Override
    public ResultDO batchCollectArtist(String uid, Collection<String> artistUids) {
        ResultDO resultDO = new ResultDO();
        if (uidIsValid(uid)) {
            for (String artistUid : artistUids) {
                if (uidIsValid(artistUid)) {
                    resultDO = collectArtistHandler(uid, artistUid);
                }
            }
        }
        return resultDO;
    }

    /**
     * 批量取消关注
     *
     * @param uid
     * @param artistUids
     * @return
     */
    @Override
    public ResultDO batchCancelCollectArtist(String uid, Collection<String> artistUids) {
        ResultDO resultDO = ResultDO.buildResult();
        if (uidIsValid(uid)) {
            for (String artistUid : artistUids) {
                if (uidIsValid(artistUid)) {
                    resultDO = cancelCollectArtistHandler(uid, artistUid);
                }
            }
        }
        return resultDO;
    }

    /**
     * 取消关注接口：
     */
    @Override
    public ResultDO cancelCollectArtist(String uid, String artistUid) {
        ResultDO resultDO = ResultDO.buildResult();
        try {
            if (!uidIsValid(uid) || !uidIsValid(artistUid)) {
                throw new APIException(FansResultCodeEnum.PARAM_IS_EMPTY_ERROR);
            }

            ResultDO tmpResultDo = restrictOperateTimes(uid);
            if (tmpResultDo != null) {
                return tmpResultDo;
            }
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, uid, artistUid);
            return resultDO;
        }

        return cancelCollectArtistHandler(uid, artistUid);
    }

    private ResultDO cancelCollectArtistHandler(String uid, String artistUid) {
        ResultDO<Integer> resultDO = ResultDO.buildResult();
        try {
            Integer tempInt = getFansNum(artistUid, false);
            fansMessageService.cancelCollectArtist(uid, artistUid);
            resultDO.setModule(tempInt);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, uid, artistUid);
        }
        return resultDO;
    }


    private Integer getFansNum(String artistUid, boolean isIncrease) {
        Integer num = fansRedisDao.getFansNum(artistUid);
        if (isIncrease) {
            num = num + 1;
        } else {
            num = num - 1;
        }
        if (num < 0) {
            num = 0;
        }
        return num;
    }

    /**
     * 查看用户关注的艺人列表
     *
     * @return
     */
    @Override
    public ResultDO<List<Artist>> queryFocusArtistInfo(QueryVO query) {
        ResultDO<List<Artist>> resultDO = ResultDO.buildResult();
        if (query == null || (query != null && !uidIsValid(query.getUid()))) {
            resultDO.setModule(new ArrayList<Artist>());
            return resultDO;
        }

        try {
            Pagination pagination = new Pagination();
            String uid = query.getUid();
            if (query.getPage() != null && query.getPageSize() != null) {
                pagination.setPage(query.getPage());
                pagination.setRows(query.getPageSize());
            }

            // 获得关注艺人的id
            List<String> focusartistUids = fansMsgHandler.getIds(uid, false, pagination);

            if (CollectionUtils.isEmpty(focusartistUids)) {
                resultDO.setModule(new ArrayList<Artist>());
                return resultDO;
            }

            // 获取User对象
            ResultDO<Map<String, User>> userResultDO = userCacheService.queryMapUserByUids(focusartistUids);
            Map<String, User> stringUserHashMap = userResultDO.getModule();
            List<Artist> artistlist = new ArrayList<Artist>();
            if (stringUserHashMap == null) {
                resultDO.setModule(artistlist);
                return resultDO;
            }

            int sizes = focusartistUids.size();

            Set<String> tmpUidSet = new HashSet<>();
            for (int i = 0; i < sizes; i++) {
                Artist artistDto = new Artist();
                String tmpUid = focusartistUids.get(i);
                if (tmpUidSet.contains(tmpUid)) {
                    continue;
                }
                User user = stringUserHashMap.get(tmpUid);
                if (null == user) {
                    continue;
                }
                tmpUidSet.add(tmpUid);
                copyUserToArtist(user, artistDto);

                artistDto.setFansCount(String.valueOf(getFansNum(tmpUid).getModule()));
                artistlist.add(artistDto);
            }

            resultDO.setModule(artistlist);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, JSON.toJSONString(query));
        }
        return resultDO;
    }

    private void copyUserToArtist(User user, Artist artist) {
        if (user != null) {
            artist.setUid(user.getUid());
            artist.setNickName(user.getNickName());
            artist.setDynamicNum(user.getPhoneNum());
            artist.setAddress(user.getAddress());
            artist.setAge(user.getAge());
            artist.setBirthday(user.getBirthday());
            artist.setChecked(user.getChecked());
            artist.setCity(user.getCity());
            artist.setColumn(user.getColumn());
            artist.setCountry(user.getCountry());
            artist.setIdentity(user.getIdentity());
            artist.setMobile(user.getMobile());
            artist.setNewUserLevel(user.getNewUserLevel());
            artist.setPhoto(user.getPhoto());
            artist.setRole(user.getRole());
            artist.setXingzuo(user.getXingzuo());
        }
    }

    /**
     * 返回指定用户已粉艺人数量
     *
     * @param uid
     * @return
     */
    public ResultDO<Integer> getFollowedNum(String uid) {
        ResultDO<Integer> resultDO = new ResultDO<>();
        if (StringUtils.isBlank(uid)) {
            setResultDOResultCode(resultDO, FansResultCodeEnum.PARAM_IS_EMPTY_ERROR);
            return resultDO;
        }
        try {
            Long size = fansMsgHandler.getFollowingSize(uid);
            if (size == null) {
                size = 0L;
            }
            resultDO.setModule(size.intValue());
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, uid);
        }
        return resultDO;
    }

    private final static String ARTIST_ID_SAVE_BY_TYPE_PREFIX = "user:artist:type:3.0.5:%s";
    private final static String USER_FOLLOW_ARTIST_BY_TYPE_PREFIX = "fans:follow:artist:by:type:%s:%s";

    /**
     * 返回用户关注指定类型的艺人
     *
     * @param query
     * @return
     */
    @Override
    public ResultDO<List<Artist>> queryCollectArtistByType(QueryVO query) {
        ResultDO<List<Artist>> resultDO = ResultDO.buildResult();
        if (query == null || StringUtils.isBlank(query.getUid()) || StringUtils.isBlank(query.getType())) {
            setResultDOResultCode(resultDO, FansResultCodeEnum.PARAM_IS_EMPTY_ERROR);
            return resultDO;
        }
        List<Artist> data = new ArrayList<>();
        try {
            int begin = 0;
            int end = 10;
            if (query.getPage() != null && query.getPageSize() != null) {
                begin = (query.getPage().intValue() - 1) * query.getPageSize().intValue();
                end = begin + query.getPageSize().intValue() - 1;
            }

            String destKey = String.format(USER_FOLLOW_ARTIST_BY_TYPE_PREFIX, query.getUid(), query.getType());
            Set<String> artistUids = cacheCommonManager.zReverseRange(destKey, begin, end);
            if (CollectionUtils.isEmpty(artistUids)) { // 缓存中没有数据，聚合数据
                List<String> sourceKey = new ArrayList<>();
                sourceKey.add(String.format(ARTIST_ID_SAVE_BY_TYPE_PREFIX, query.getType()));
                sourceKey.add(FansConstant.REDIS_USER_FOLLOWING_ARTIST_ZSET_PREFIX + query.getUid());
                String tmpKey = destKey + ":tmp";
                cacheCommonManager.zInterStore(sourceKey, tmpKey, 60, RedisZSetCommands.Aggregate.MAX, null);
                Set<String> tmpartistUidSet = cacheCommonManager.zReverseRange(tmpKey, 0, -1);
                List<String> tmpartistUidList = new ArrayList<>(tmpartistUidSet);
                List<Object> tmpLenths = cacheCommonManager.getZSetLength(tmpartistUidList);
                Map<String, Double> tmpMap = new HashMap<>();
                for (int i = 0; i < tmpartistUidList.size(); i++) {
                    String artistUid = tmpartistUidList.get(i);
                    Long fansNum = (Long) tmpLenths.get(i);
                    tmpMap.put(artistUid, fansNum.doubleValue());
                }
                cacheCommonManager.zsetAddMore(destKey, tmpMap, 5 * 60);
                artistUids = cacheCommonManager.zReverseRange(destKey, begin, end);
            }

            if (CollectionUtils.isNotEmpty(artistUids)) {
                List<String> artistUidList = new ArrayList<>(artistUids);
                Map<String, User> userMap = userCacheService.queryMapUserByUids(artistUidList).getModule();
                Map<String, RankDto> rankDtoMap = batchQueryRankDto(artistUidList);
                buildArtists(artistUidList, userMap, rankDtoMap, data);
            }
            resultDO.setModule(data);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, JSON.toJSONString(query));
        }
        return resultDO;
    }

    private Map<String, RankDto> batchQueryRankDto(List<String> artistUidList) {
        Map<String, RankDto> rankDtoMap = new HashMap<>();
        try {
            ResultDO<Map<String, RankDto>> rankDtoResultDO = artistTotalPopularityService.batchQueryArtistRankDtoMap(artistUidList);
            if (ResultDO.isSuccess(rankDtoResultDO)) {
                rankDtoMap = rankDtoResultDO.getModule();
            }
        } catch (Exception e) {
            LoggerUtils.error(logger, e, ModuleResultCode.FANS, JSON.toJSONString(artistUidList));
        }
        return rankDtoMap;
    }

    /**
     * 查看用户关注的艺人id集合
     *
     * @param uid
     * @return
     */
    @Override
    public ResultDO<List<String>> queryFocusIds(String uid) {
        ResultDO<List<String>> resultDO = ResultDO.buildResult();
        if (StringUtils.isBlank(uid)) {
            setResultDOResultCode(resultDO, FansResultCodeEnum.PARAM_IS_EMPTY_ERROR);
            return resultDO;
        }
        try {
            Set<String> uidList = fansMsgHandler.getZSetRedisValues(uid, false, 0, -1);
            List<String> tmpList = new ArrayList<>(uidList);
            resultDO.setModule(tmpList);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, uid);
        }
        return resultDO;
    }

    /**
     * 返回指定用户已粉艺人按类型区分的ID列表
     *
     * @param uid
     * @param type 0返回所有 100001明星100002栏目
     * @return
     */
    @Override
    public ResultDO<List<String>> queryFocusIdsByType(String uid, String type) {
        ResultDO<List<String>> resultDO = new ResultDO<>();
        if (StringUtils.isBlank(uid) || StringUtils.isBlank(type)) {
            resultDO.setModule(new ArrayList<String>());
            return resultDO;
        }
        List<String> data = null;
        try {
            if (type.equals("0")) {
                Set<String> uidList = fansMsgHandler.getZSetRedisValues(uid, false, 0, -1);
                data = new ArrayList<>(uidList);
            } else {
                String destKey = String.format(USER_FOLLOW_ARTIST_BY_TYPE_PREFIX, uid, type);
                List<String> sourceKey = new ArrayList<>();
                sourceKey.add(String.format(ARTIST_ID_SAVE_BY_TYPE_PREFIX, type));
                sourceKey.add(FansConstant.REDIS_USER_FOLLOWING_ARTIST_ZSET_PREFIX + uid);
                String tmpKey = destKey + ":tmp";
                cacheCommonManager.zInterStore(sourceKey, tmpKey, 60, RedisZSetCommands.Aggregate.MAX, null);
                Set<String> tmpartistUidSet = cacheCommonManager.zReverseRange(tmpKey, 0, -1);
                data = new ArrayList<>(tmpartistUidSet);
            }
            resultDO.setModule(data);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, uid, type);
        }
        return resultDO;
    }

    @Override
    public Set<String> queryFocusIdFromRedis(String uid, int start, int end) {
        if (start < 0) {
            start = 0;
        }
        // 现在查询出来的是艺人的粉丝ID数据，与接口功能不符 ---2016-10-31修改 darren.dai
        Set<String> uidSet = fansMsgHandler.getZSetRedisValues(uid, true, start, end);
        return uidSet;
    }

    /**
     * 查看用户关注的艺人详情列表
     *
     * @return
     */
    @Override
    public ResultDO<List<Artist>> queryCollectArtist(QueryVO query) {
        ResultDO<List<Artist>> resultDO = new ResultDO<List<Artist>>();
        try {
            if (query == null || (query != null && StringUtils.isBlank(query.getUid()))) {
                resultDO.setModule(new ArrayList<Artist>());
                return resultDO;
            }

            Pagination pagination = new Pagination();
            if (query.getPage() != null && query.getPageSize() != null) {
                pagination.setRows(query.getPageSize());
                pagination.setPage(query.getPage());
            }
            String uid = query.getUid();
            if (!uidIsValid(uid)) {
                throw new APIException(FansResultCodeEnum.PARAM_IS_EMPTY_ERROR);
            }
            int start = pagination.getCurrentResult();
            int end = start + pagination.getRows() - 1;
            // 获得关注艺人的id
            List<String> focusartistUids = fansMsgHandler.getIdsByRange(uid, false, start, end);

            if (CollectionUtils.isEmpty(focusartistUids)) {
                List<Artist> empty = new ArrayList<Artist>();
                return new ResultDO<>(empty);
            }
            ResultDO<Map<String, User>> artist = userCacheService.queryMapUserByUids(focusartistUids);
            Map<String, User> userMap = artist.getModule();
            if (userMap == null) {
                throw new APIException(FansResultCodeEnum.QUERY_USER_INFO_ERROR);
            }

            Map<String, RankDto> rankDtoMap = batchQueryRankDto(focusartistUids);

            List<Artist> artistList = new ArrayList<Artist>();
            buildArtists(focusartistUids, userMap, rankDtoMap, artistList);
            resultDO.setModule(artistList);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, JSON.toJSONString(query));
        }
        return resultDO;
    }

    private void buildArtists(List<String> artistUidList, Map<String, User> userMap,
                              Map<String, RankDto> rankDtoMap, List<Artist> data) throws InvocationTargetException, IllegalAccessException {
        for (int i = 0; i < artistUidList.size(); i++) {
            Artist artistDto = new Artist();
            String artistUid = artistUidList.get(i);
            User user = null;
            if (userMap != null) {
                user = userMap.get(artistUid);
            }
            if (null == user) {
                continue;
            }
            copyUserToArtist(user, artistDto);

            RankDto rankDto = rankDtoMap.get(artistUid);
            int hotValue = 0;
            if (null != rankDto) {
                hotValue = rankDto.getPopularityInc();
            }

            artistDto.setHotValue(String.valueOf(hotValue));
            artistDto.setFansCount(String.valueOf(getFansNum(artistUid).getModule()));
            data.add(artistDto);
        }
    }

    /**
     * 用户是否关注指定艺人
     */
    @Override
    public ResultDO<Boolean> isFollowed(String artistUid, String uid) {
        ResultDO<Boolean> resultDO = ResultDO.buildResult();
        if (StringUtils.isBlank(uid) || StringUtils.isBlank(artistUid)) {
            setResultDOResultCode(resultDO, FansResultCodeEnum.PARAM_IS_EMPTY_ERROR);
            return resultDO;
        }
        try {
            Boolean b = fansMsgHandler.isFollowing(uid, artistUid);
            resultDO.setModule(b);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, artistUid, uid);
        }
        return resultDO;
    }

    /**
     * 返回一组艺人的粉丝数量
     *
     * @param artistUids
     * @return
     */
    public ResultDO<Map<String, Long>> queryFansNum(List<String> artistUids) {
        ResultDO<Map<String, Long>> resultDO = new ResultDO<>();
        Map<String, Long> fansNumMap = new HashMap<>();
        try {
            if (CollectionUtils.isNotEmpty(artistUids)) {
                String redisKey = "";
                List<String> redisKeyList = new ArrayList<>();
                for (String artistUid : artistUids) {
                    if (StringUtils.isNotBlank(artistUid)) {
                        redisKey = FansConstant.REDIS_ARTIST_FANS_IDS_ZSET_PREFIX + artistUid;
                        redisKeyList.add(redisKey);
                    }
                }
                List<Object> fansNumList = cacheCommonManager.getZSetLength(redisKeyList);
                int index = 0;
                for (String artistUid : artistUids) {
                    Long fansNum = new Long(0);
                    if (index < fansNumList.size()) {
                        fansNum = (Long) fansNumList.get(index);
                    }
                    if (fansNum <= 0) {
                        fansNum = fansRedisDao.getFansNum(artistUid).longValue();
                    }
                    fansNumMap.put(artistUid, fansNum);
                    index++;
                }
            }
            resultDO.setModule(fansNumMap);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, JSON.toJSONString(artistUids));
        }
        return resultDO;
    }

    /**
     * 查询用户是否关注指定艺人
     *
     * @param artists
     * @param uid
     * @return
     */
    @Override
    public ResultDO<Map<String, Boolean>> queryIsFolllows(List<String> artists, String uid) {
        ResultDO<Map<String, Boolean>> resultDO = new ResultDO<>();
        if (StringUtils.isBlank(uid) || CollectionUtils.isEmpty(artists)) {
            setResultDOResultCode(resultDO, FansResultCodeEnum.PARAM_IS_EMPTY_ERROR);
            return resultDO;
        }
        try {
            Map<String, Boolean> resultMap = new HashMap<>();
            for (String artistUid : artists) {
                if (StringUtils.isEmpty(artistUid)) {
                    continue;
                }
                Boolean b = fansMsgHandler.isFollowing(uid, artistUid);
                resultMap.put(artistUid, b);
            }

            resultDO.setModule(resultMap);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, artists, uid);
        }
        return resultDO;
    }

    /**
     * 查询艺人粉丝增加数
     *
     * @param artistUid
     * @return
     */
    @Override
    public ResultDO<Integer> getFansIncrement(String artistUid) {
        ResultDO<Integer> resultDO = new ResultDO<Integer>();
        if (StringUtils.isBlank(artistUid)) {
            setResultDOResultCode(resultDO, FansResultCodeEnum.PARAM_IS_EMPTY_ERROR);
            return resultDO;
        }
        try {
            Integer inc = fansRedisDao.getFansIncrement(artistUid);
            if (inc != null) {
                resultDO.setModule(inc);
            } else {
                resultDO.setModule(0);
            }
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, artistUid);
        }
        return resultDO;
    }

    /**
     * 查看艺人粉丝列表详情
     *
     * @return
     */
    @Override
    public ResultDO<List<FansInfo>> getFansListByUid(QueryVO query) {
        ResultDO<List<FansInfo>> resultDO = new ResultDO<>();
        if (query == null || (query != null && StringUtils.isBlank(query.getUid()))) {
            setResultDOResultCode(resultDO, FansResultCodeEnum.PARAM_IS_EMPTY_ERROR);
            return resultDO;
        }

        try {
            String artistUid = query.getUid();
            Pagination pagination = new Pagination();
            if (query.getPage() != null && query.getPageSize() != null) {
                pagination.setRows(query.getPageSize());
                pagination.setPage(query.getPage());
            }

            int start = pagination.getCurrentResult();
            int end = pagination.getCurrentResult() + pagination.getRows() - 1;
            List<FansInfo> fansList = new ArrayList<>();
            Set<DefaultTypedTuple<String>> redisData = fansMsgHandler.getRangeWithScores(artistUid, true, start, end);
            List<String> fansUids = new ArrayList<>();
            Map<String, Date> fansUidDateMap = new HashMap<>();
            fansMsgHandler.getUidList(redisData, fansUids);
            fansMsgHandler.getUidTimeMap(redisData, fansUidDateMap);

            if (!CollectionUtils.isEmpty(fansUids)) {
                // 获取用户信息
                Map<String, User> userMap = userCacheService.queryMapUserByUids(fansUids).getModule();
                if (userMap.size() > 0) {
                    List<String> keyList = fansMsgHandler.getIdsByRange(artistUid, false, 0, -1);

                    for (int i = 0; i < fansUids.size(); i++) {
                        String uid = fansUids.get(i);
                        FansInfo fans = new FansInfo();
                        fans.setUid(uid);
                        Date date = fansUidDateMap.get(uid);
                        if (date != null) {
                            fans.setTime(DateUtils.formatDateTime(date));
                        }
                        User user = userMap.get(uid);
                        if (user != null) {
                            fans.setRole(user.getRole());
                            fans.setAvarta(user.getPhoto());
                            fans.setNickName(user.getNickName());
                            // 设置互粉标记
                            if (user.getRole() != 0) {
                                fans.setIsFans(keyList.contains(uid));
                            }
                        }
                        fansList.add(fans);
                    }
                }
            }

            resultDO.setModule(fansList);
            String redisKey = FansConstant.REDIS_ARTIST_FANS_INCREMENT_PREFIX + artistUid;
            cacheCommonManager.setValueAndExpire(redisKey, "0", CacheCommonManager.RedisTemplateEnum.STRINGSERIALIZER, -1);
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, JSON.toJSONString(query));
        }
        return resultDO;
    }

    /**
     * 查看关注指定艺人的粉丝uid列表
     *
     * @param artistUid
     * @return
     */
    @Override
    public ResultDO<List<String>> queryFansIds(String artistUid) {
        ResultDO<List<String>> resultDO = new ResultDO<>();
        if (StringUtils.isBlank(artistUid)) {
            setResultDOResultCode(resultDO, FansResultCodeEnum.PARAM_IS_EMPTY_ERROR);
            return resultDO;
        }
        try {
            List<String> uidList = fansMsgHandler.getIds(artistUid, true, null);
            if (CollectionUtils.isNotEmpty(uidList)) {
                resultDO.setModule(uidList);
            } else {
                resultDO.setModule(new ArrayList<String>());
            }
        } catch (Exception e) {
            LoggerUtils.errorAndResultDO(logger, e, ModuleResultCode.FANS, resultDO, artistUid);
        }
        return resultDO;
    }

    private ResultDO restrictOperateTimes(String uid) {
        // 用户操作频率限制，1秒内不能再次操作
        String redisOperateKey = getUserOperateKey(uid);
        if (cacheCommonManager.hasKey(redisOperateKey)) {
            ResultDO resultDO = new ResultDO();
            setResultDOResultCode(resultDO, FansResultCodeEnum.COLLECT_ARTIST_FREQUENTLY_OPERATED_ERROR);
            return resultDO;
        } else {
            cacheCommonManager.setValueAndExpire(redisOperateKey, "1", CacheCommonManager.RedisTemplateEnum.STRINGSERIALIZER, 1);
            return null;
        }
    }

    private String getUserOperateKey(String uid) {
        return FansConstant.REDIS_USER_OPERATE_PREFIX + uid;
    }
}
